Shader "Instanced/InstancedSurfaceShader" {
    Properties {
        _Color ("Color", Color) = (0.000000,0.000000,1.000000,1.000000)
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        // Physically based Standard lighting model
        #pragma multi_compile _ _SHOW_DENSITY
        #pragma surface surf Standard addshadow fullforwardshadows
        #pragma multi_compile_instancing
        #pragma instancing_options procedural:setup

    #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
        StructuredBuffer<float3> positionBuffer;
	    StructuredBuffer<int> neighborsCounterBuffer;
    #endif
	    
		uniform float scale;
		float density;

        void setup()
        {
			density = 0;
        #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
            float3 data = positionBuffer[unity_InstanceID];
            unity_ObjectToWorld._11_21_31_41 = float4(scale, 0, 0, 0);
            unity_ObjectToWorld._12_22_32_42 = float4(0, scale, 0, 0);
            unity_ObjectToWorld._13_23_33_43 = float4(0, 0, scale, 0);
            unity_ObjectToWorld._14_24_34_44 = float4(data, 1);
            unity_WorldToObject = unity_ObjectToWorld;
            unity_WorldToObject._14_24_34 *= -1;
            unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
			density = neighborsCounterBuffer[unity_InstanceID] / 50.0f;
        #endif
        }

        float _Glossiness;
        float _Metallic;
		float4 _Color;

		struct Input {
			float i;
		};

        void surf (Input i, inout SurfaceOutputStandard o) {
#ifdef _SHOW_DENSITY
			o.Albedo = float3(density, 0, 0);
#else
			o.Albedo = _Color.rgb;
#endif
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = _Color.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}